﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using A2DFramework.EsbService.DistributedEsb.Configuration;
using System.Threading;
using A2DFramework.EsbService.DistributedEsb.SessionSupport;
using A2DFramework.InstanceService;
using A2DFramework.QueueService;

namespace A2DFramework.EsbService.DistributedEsb
{
    public class CommandHandlerListener
    {
        private List<IRequestHandlerWorker> handlers = new List<IRequestHandlerWorker>();
        List<Type> cmdTypes = new List<Type>();
        CommandHandlerProxy proxy = new CommandHandlerProxy();
        private IQueue queueSrv = ObjectFactory.Resolve<IQueue>();

        public void AddHandler(IRequestHandlerWorker handler)
        {
            this.handlers.Add(handler);
        }
        public void Start()
        {
            this.handlers.ForEach(t => proxy.AddHandler(t));

            CollectCommandTypes();

            //run thread each
            foreach(var cmdType in cmdTypes)
                ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessQueue), cmdType);
        }

        private void CollectCommandTypes()
        {
            foreach (var handler in this.handlers)
            {
                foreach (var t in handler.GetType().GetInterfaces())
                {
                    if (!t.IsGenericType)
                        continue;

                    foreach (var args in t.GetGenericArguments())
                    {
                        if (typeof(EsbRequestWrapper).IsAssignableFrom(args))
                        {
                            cmdTypes.Add(args);
                        }
                    }
                }
            }
        }
        public void ProcessQueue(object state)
        {
            Type cmdType = (Type)state;

           
            while (true)
            {
                Message<EsbRequestWrapper> msg = queueSrv.GetRequestFromClient<EsbRequestWrapper>();
                EsbRequestWrapper cmd = msg.Body;

                Console.WriteLine(string.Format("New Message received from msmq: {0}", msg.ID));

                ISessionContext session = new SessionContext(cmd.SessionID, cmd.SessionItems);
                EsbResponseWrapper cmdResult = proxy.Handler(cmd, session);

                //发送应答消息
                queueSrv.SendResponse2Client<EsbResponseWrapper>(cmdResult, msg.ID);
            }
        }
    }
}
